﻿/*
value.js

The MIT License

Copyright (c) 2011 Yuya.Yamaguchi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// グローバル変数の管理を行う

//-----------------------------
//! グローバル変数型
/*!
 * @param	name	変数名
 * @param	def		デフォルト値
 * @param	val		現在値
*/
function EspGlobalValueData(name, def, val){
	this.name = name;
	this.def = def;
	this.val = val;
}

//-----------------------------
//! グローバル変数グループ型
function EspGlobalValueGroupData(name, def){
	this.name = name;
	this.def = def;
}

//-----------------------------
//! グローバル変数グループインスタンス
function EspGlobalValueGroupInstance(name){
	this.name = name;
	this.val = new Array();
}

//! インスタンスに要素を追加する
EspGlobalValueGroupInstance.prototype.add = function(val){
	this.val.push(val);
}

//! インスタンスの要素を削除する
EspGlobalValueGroupInstance.prototype.remove = function(index){
	this.val.splice(index, 1);
}

//! 名前を変える
EspGlobalValueGroupInstance.prototype.setName = function(name){
	this.name = name;
}

//! 名前を取得する
EspGlobalValueGroupInstance.prototype.getName = function(){
	return this.name;
}
//! インスタンスの値を取得する
EspGlobalValueGroupInstance.prototype.get = function(index){
	return this.val[index];
}

//! インスタンスに値を設定する
EspGlobalValueGroupInstance.prototype.set = function(index, val){
	this.val[index] = val;
}

//-----------------------------
//! グローバル変数グループ
function EspGlobalValueGroup(name){
	this.name = name;
	// 変数定義
	this.defs = new Array();
	// そのインスタンス
	this.instance = new Array();
}

//! グループの定義数を取得する
EspGlobalValueGroup.prototype.getDefCount = function(){
	return this.defs.length;
}

//! グループに定義を追加する
EspGlobalValueGroup.prototype.addDef = function(name, def){
	this.defs.push(new EspGlobalValueGroupData(name, def));
	// 既にインスタンスがある場合はインスタンスを編集する
	var count = this.instance.length;
	for(var i = 0; i < count; i++){
		this.instance[i].add(def);
	}
}
//! グループから定義を削除する
EspGlobalValueGroup.prototype.removeDef = function(index){
	this.defs.splice(index, 1);
	// 既にインｓタンスがある場合はインスタンスを編集する
	var count = this.instance.length;
	for(var i = 0; i < count; i++){
		this.instance[i].remove(index);
	}
}

//! グループの要素を取得する
EspGlobalValueGroup.prototype.getDef = function(index){
	return this.defs[index];
}

//! グループの要素を設定する
EspGlobalValueGroup.prototype.setDef = function(index, name, def){
	this.defs[index].name = name;
	this.defs[index].def = def;
}

//! インスタンス数を取得する
EspGlobalValueGroup.prototype.getInstanceCount = function(){
	return this.instance.length;
}

//! インスタンスを増やす
EspGlobalValueGroup.prototype.addInstance = function(name){
	var inst = new EspGlobalValueGroupInstance(name);
	var count = this.defs.length;
	for(var i = 0; i < count; i++){
		inst.add(this.defs[i].def);
	}
	this.instance.push(inst);
}

//! インスタンスを削除する
EspGlobalValueGroup.prototype.removeInstance = function(index){
	this.instance.splice(index, 1);
}

//! インスタンスを参照する
EspGlobalValueGroup.prototype.getInstance = function(inst){
	return this.instance[inst];
}

//! インスタンス名を取得する
EspGlobalValueGroup.prototype.getInstanceName = function(inst){
	return this.instance[inst].name;
}
//! インスタンスの値を取得する
EspGlobalValueGroup.prototype.getValue = function(inst, index){
	return this.instance[inst].val[index];
}

//! インスタンス名を設定する
EspGlobalValueGroup.prototype.setInstanceName = function(inst, name){
	return this.instance[inst].name = name;
}

//! インスタンスの値を設定する
EspGlobalValueGroup.prototype.setValue = function(inst, index, val){
	this.instance[inst].val[index] = val;
}

//! 選択要素をリセットする
EspGlobalValueGroup.prototype.resetValue = function(inst, index){
	this.instance[inst].val[index] = this.def[index].def;
}

//! 選択インスタンスの要素をリセットする
EspGlobalValueGroup.prototype.resetInstance = function(inst){
	var count = this.def.length;
	for(var i = 0; i < count; i++){
		this.instance[inst].val[i] = this.def[i].def;
	}
}

//! 全てのインスタンスの要素をリセットする
EspGlobalValueGroup.prototype.resetAll = function(){
	var count = this.instance.length;
	for(var i = 0; i < count; i++){
		this.resetInstance(i);
	}
}

//-----------------------------
//! グローバル変数管理クラス
function EspGlobalValue(){
	this.group = new Array();
	this.value = new Array();
}

EspGlobalValue.strageNameDefineNormal = "globalValueDefine";
EspGlobalValue.strageNameDefineGroup = "globalValueDefineGroup";
EspGlobalValue.strageNameData = "globalValueData";

//! 要素数を取得する
EspGlobalValue.prototype.getCount = function(){
	return this.value.length;
}

//! 変数を参照する
EspGlobalValue.prototype.get = function(index){
	return this.value[index];
}

//! 変数値を設定する
EspGlobalValue.prototype.set = function(index, value){
	this.value[index].val = value;
}

//! 通常データ定義をローカルストレージに保存する
EspGlobalValue.prototype.saveDefineNormal = function(){
	// JSONにそのまま書きだす
	var obj = new Object();
	obj.data = new Array();
	var count = this.getCount();
	for(var i = 0; i < count; i++){
		var dat = this.getValue(i);
		obj.data[i] = new Object();
		obj.data[i].name = dat.name;
		obj.data[i].def = dat.def;
		obj.data[i].val = dat.val;
	}
	var val = JSON.stringify(obj);
	localStorage.setItem(EspGlobalValue.strageNameDefineNormal, val );
//	console.log("保存>>>>>>>");
//	console.log(val);
//	console.log("保存<<<<<<<");
}
//! グループデータ定義をローカルストレージに保存する
EspGlobalValue.prototype.saveDefineGroup = function(){
	var obj = new Object();
	var count = this.getGroupCount();
	obj.group = new Array(count);
	for(var i = 0; i < count; i++){
		// グループ定義
		var gname = this.getGroupName(i);
		obj.group[i] = new Object();
		obj.group[i].name = gname;
		var defCount = this.getGroupDefCount(i);
		obj.group[i].def = new Array(defCount);
		for(var j = 0; j < defCount; j++){
			var def = this.getGroupDef(i, j);
			obj.group[i].def[j] = new Object();
			obj.group[i].def[j].name = def.name;
			obj.group[i].def[j].def = def.def;
		}
		// インスタンスデータ
		var insCount = this.getInstanceCount(i);
		obj.group[i].instance = new Array(insCount);
		for(var j = 0; j < insCount; j++){
			var inst = this.getInstance(i, j);
			obj.group[i].instance[j] = new Object();
			obj.group[i].instance[j].val = new Array(defCount);
			obj.group[i].instance[j].name = inst.name;
			for(var k = 0; k < defCount; k++){
				obj.group[i].instance[j].val[k] = new Object();
				obj.group[i].instance[j].val[k].val = inst.val[k];
			}
		}
	}
	var val = JSON.stringify(obj);
	localStorage.setItem(EspGlobalValue.strageNameDefineGroup, val );
//	console.log("保存>>>>>>>");
//	console.log(val);
//	console.log("保存<<<<<<<");
}
//! 定義をローカルストレージに保存する
EspGlobalValue.prototype.saveDefine = function(){
	this.saveDefineNormal();
	this.saveDefineGroup();
}

//! 通常データ定義をネットワークかローカルストレージでロードする
EspGlobalValue.prototype.loadDefineNormal = function(){
	// 一度グローバル変数をクリア
	this.value.length = 0;
	var val = localStorage[EspGlobalValue.strageNameDefineNormal];
	if(val){
	//	console.log("読込>>>>>>>");
	//	console.log(val);
	//	console.log("読込<<<<<<<");
		var obj = JSON.parse(val);
		for(var i = 0; i < obj.data.length; i++){
			this.addNewValue(obj.data[i].name, obj.data[i].def, obj.data[i].val);
		}
	}
}
//! グループデータ定義をネットワークかローカルストレージでロードする
EspGlobalValue.prototype.loadDefineGroup = function(){
	// グループをクリア
	this.group.length = 0;
	var val = localStorage[EspGlobalValue.strageNameDefineGroup];
	if(val){
	//	console.log("読込>>>>>>>");
	//	console.log(val);
	//	console.log("読込<<<<<<<");
		var obj = JSON.parse(val);
		for(var i = 0; i < obj.group.length; i++){
			this.addGroup(obj.group[i].name);
			for(var j = 0; j < obj.group[i].def.length; j++){
				this.addGroupDef(i, obj.group[i].def[j].name, obj.group[i].def[j].def);
			}
			for(var j = 0; j < obj.group[i].instance.length; j++){
				this.addInstance(i, obj.group[i].instance[j].name);
				for(var k = 0; k < obj.group[i].instance[j].val.length; k++){
					this.setInstanceValue(i, j, k, obj.group[i].instance[j].val[k].val);
				}
			}
		}
	}
}
//! 定義をネットワークかローカルストレージでロードする
EspGlobalValue.prototype.loadDefine = function(){
	this.loadDefineNormal();
	this.loadDefineGroup();
}

//! 変数をローカルストレージに保存する
EspGlobalValue.prototype.saveData = function(){
	// これでJSON対応できるのか?
	var obj = new Object();
	var objCount = this.getCount();
	obj.count = objCount;
	for(var i = 0; i < objCount; i++){
		var dat = this.getValue(i);
		var index = "data"+i;
		obj[index] = new Object;
		obj[index].name = dat.name;
		obj[index].val = dat.val;
	}
	var val = JSON.stringify(obj);
	localStorage.setItem(EspGlobalValue.strageNameData, val );
}

//! 変数をローカルストレージからロードする
EspGlobalValue.prototype.loadData = function(){
	;
}

//! 変数を初期値で初期化する
EspGlobalValue.prototype.reset = function(){
	var objCount = this.getCount();
	for(var i = 0; i < objCount; i++){
		this.value[i].val = this.value[i].def;
	}
}

/////////////////////////////////////
// エディタから使用

//! 要素を参照する
EspGlobalValue.prototype.getValue = function(index){
	return this.value[index];
}

//! 要素を追加する
EspGlobalValue.prototype.addNewValue = function(name, def, val){
	// 同じ変数名がないか調査
	this.value.push(new EspGlobalValueData(name, def, val));
}

//! 要素を削除する
EspGlobalValue.prototype.removeValue = function(index){
	this.value.splice(index, 1);
}

//! 要素を変更する
EspGlobalValue.prototype.modifiValue = function(index, name, def, val){
	// 同じ変数名がないか調査、必要に応じてリネーム
	this.value[index].name = name;
	this.value[index].def = def;
	this.value[index].val = val;
}

//! グループを追加する
EspGlobalValue.prototype.addGroup = function(name){
	this.group.push(new  EspGlobalValueGroup(name));
}

//! グループを削除する
EspGlobalValue.prototype.removeGroup = function(group){
	this.group.splice(group, 1);
}

//! グループ数を取得する
EspGlobalValue.prototype.getGroupCount = function(){
	return this.group.length;
}

//! グループ名を取得する
EspGlobalValue.prototype.getGroupName = function(index){
	return this.group[index].name;
}

//! グループ名を変更する
EspGlobalValue.prototype.setGroupName = function(group, name){
	this.group[group].name = name;
}

//! グループ要素数を取得する
EspGlobalValue.prototype.getGroupDefCount = function(group){
	return this.group[group].getDefCount();
}

//! グループ要素を追加する
EspGlobalValue.prototype.addGroupDef = function(group, name, def){
	this.group[group].addDef(name, def);
}

//! グループ要素を削除する
EspGlobalValue.prototype.removeGroupDef = function(group, index){
	this.group[group].removeDef(index);
}

//! グループ要素を取得する
EspGlobalValue.prototype.getGroupDef = function(group, index){
	return this.group[group].getDef(index);
}

//! グループ要素を変更する
EspGlobalValue.prototype.setGroupDef = function(group, index, name, def){
	this.group[group].setDef(index, name, def);
}

//! グループインスタンス数を取得する
EspGlobalValue.prototype.getInstanceCount = function(group){
	return this.group[group].getInstanceCount();
}

//! グループインスタンスを追加する
EspGlobalValue.prototype.addInstance = function(group, name){
	this.group[group].addInstance(name);
}

//! インスタンスを削除する
EspGlobalValue.prototype.removeInstance = function(group, instance){
	this.group[group].removeInstance(instance);
}

//! インスタンスを参照する
EspGlobalValue.prototype.getInstance = function(group, instance){
	return this.group[group].getInstance(instance);
}

//! インスタンスの名前を取得する
EspGlobalValue.prototype.getInstanceName = function(group, instance){
	return this.group[group].getInstanceName(instance);
}
//! インスタンスの値を取得する
EspGlobalValue.prototype.getInstanceValue = function(group, instance, index){
	return this.group[group].getValue(instance, index);
}

//! インスタンスの名前を設定する
EspGlobalValue.prototype.setInstanceName = function(group, instance, name){
	return this.group[group].setInstanceName(instance, name);
}
//! インスタンスの値を設定する
EspGlobalValue.prototype.setInstanceValue = function(group, instance, index, value){
	this.group[group].setValue(instance, index, value);
}

//! インスタンスの値をリセットする
EspGlobalValue.prototype.resetInstanceValue = function(group, instance, index){
	this.group[group].resetValue(instance, index);
}

//! インスタンスをリセットする
EspGlobalValue.prototype.resetInstance = function(group, instance){
	this.group[group].resetInstance(instance);
}

//! グループ内のインスタンスをリセットする
EspGlobalValue.prototype.resetInstanceAll = function(group){
	this.group[group].resetAll();
}

var espGlobalValue = new EspGlobalValue();


